// @note:依赖BattleVictory.js
import { LevelUpParams as Params} from '@swda/configs/params'


let SWDA_LevelUp = {};

//=============================================================================
// BattleManager
//=============================================================================
// 获得战斗奖励前、后，获取等级数据
SWDA_LevelUp.BattleManager_gainRewards =
    BattleManager.gainRewards;
BattleManager.gainRewards = function () {
    this.prepareVictoryPreLevel();
    SWDA_LevelUp.BattleManager_gainRewards.call(this);
    this.prepareVictoryPostLevel();
};


BattleManager.prepareVictoryPreLevel = function () {
    var length = $gameParty.allMembers().length;
    this._leveledActors = [];
    for (var i = 0; i < length; ++i) {
        var actor = $gameParty.allMembers()[i];
        if (!actor) continue;
        actor._preVictoryLv = actor._level;
        actor._preVictoryParams = [];
        actor._preVictoryParams.push(actor.mhp);
        actor._preVictoryParams.push(actor.mmp);
        actor._preVictoryParams.push(actor.maxTp());
        actor._preVictoryParams.push(actor.atk);
        actor._preVictoryParams.push(actor.def);
        actor._preVictoryParams.push(actor.mat);
        actor._preVictoryParams.push(actor.mdf);
        actor._preVictoryParams.push(actor.agi);
        actor._preVictoryParams.push(actor.luk);

        actor._victoryPhase = true;
        actor._victorySkills = [];
    }
};

BattleManager.prepareVictoryPostLevel = function () {
    var length = $gameParty.allMembers().length;
    for (var i = 0; i < length; ++i) {
        var actor = $gameParty.allMembers()[i];
        if (!actor) continue;
        if (actor._preVictoryLv === actor._level) continue;
        this._leveledActors.push(actor);
        actor._postVictoryParams = [];
        actor._postVictoryParams.push(actor.mhp);
        actor._postVictoryParams.push(actor.mmp);
        actor._postVictoryParams.push(actor.maxTp());
        actor._postVictoryParams.push(actor.atk);
        actor._postVictoryParams.push(actor.def);
        actor._postVictoryParams.push(actor.mat);
        actor._postVictoryParams.push(actor.mdf);
        actor._postVictoryParams.push(actor.agi);
        actor._postVictoryParams.push(actor.luk);
    }
};

BattleManager.aftermathLeveledActors = function () {
    return this._leveledActors;
};

BattleManager.playLevelUpMe = function () {
    const levelUpBgm = {
        name: Params.MeName,
        volume: Params.MeVol,
        pitch: Params.MePitch,
        pan: Params.MePan
    };
    AudioManager.playMe(levelUpBgm);
};

//=============================================================================
// Window_LevelUp
//=============================================================================

function Window_LevelUp() {
    this.initialize.apply(this, arguments);
}

Window_LevelUp.prototype = Object.create(Window_Base.prototype);
Window_LevelUp.prototype.constructor = Window_LevelUp;

Window_LevelUp.prototype.initialize = function (actor) {
    this._actor = actor;
    var width = this.windowWidth();
    var height = this.windowHeight();
    var x = (Graphics.boxWidth - width) / 2;
    var y = (Graphics.boxHeight - height) / 2;
    Window_Base.prototype.initialize.call(this, x, y, width, height);
    this.openness = 0;
    this.createPresets();
    this.refresh();
};

Window_LevelUp.prototype.windowWidth = function () {
    return 496;
};

Window_LevelUp.prototype.windowHeight = function () {
    if (this._actor._victorySkills.length > 0)
        return this.fittingHeight(10.5 + Math.min(this._actor._victorySkills.length, this.maxVisibleSkills()) + 1);
    else
        return this.fittingHeight(10.5);
};

Window_LevelUp.prototype.maxVisibleSkills = function () {
    return 5;
};

Window_LevelUp.prototype.createPresets = function () {
    var actor = this._actor;
    this._paramNameWidth = this.textWidth(TextManager.level);
    this._paramValueWidth = this.textWidth(Yanfly.Util.toGroup(actor.maxLevel()));
    this._arrowWidth = this.textWidth('\u2192' + ' ');
    var buffer = this.textWidth(' ');
    for (var i = 0; i < 8; ++i) {
        var value1 = this.textWidth(TextManager.param(i));
        var value2 = this.textWidth(Yanfly.Util.toGroup(this._actor.paramMax(i)));
        this._paramNameWidth = Math.max(value1, this._paramNameWidth);
        this._paramValueWidth = Math.max(value2, this._paramValueWidth);
    }
    this._bonusValueWidth = this._paramValueWidth;
    this._bonusValueWidth += this.textWidth('(+)') + buffer;
    this._paramNameWidth += buffer;
    this._paramValueWidth = this._paramValueWidth * 1.5;
    var validArea = this.itemRect(0).width;
    if (this._paramNameWidth + this._paramValueWidth * 2 + this._arrowWidth +
        this._bonusValueWidth > validArea) this._bonusValueWidth = 0;
};

Window_LevelUp.prototype.setActor = function (actor) {
    this._actor = actor;
    this.createPresets();
    this.refresh();
};

Window_LevelUp.prototype.refresh = function () {
    this.contents.clear();
    this.resetFontSettings();
    this.resetTextColor();
    this.drawTitle();
    this.drawStatChanges();
    this.drawLearnedSkills(this.itemRect(10));
};


Window_LevelUp.prototype.itemRect = function (index) {
    var rect = new Rectangle();
    rect.x = 0;
    // 不包含0的情况
    rect.y = (index + 0.5) * this.lineHeight();
    rect.width = this.contents.width;
    rect.height = this.lineHeight();
    return rect;
};



Window_LevelUp.prototype.drawTitle = function () {
    var textTitle = TextManager.levelUp.format(this._actor.name(), TextManager.level, this._level);
    this.changeTextColor(this.systemColor());
    this.setTitleFont();
    this.drawText(textTitle, 0, 4, this.contents.width, 'center');
    this.resetFontSettings();
    this.drawHorzLine(this.lineHeight() *1.25);
};

Window_LevelUp.prototype.drawStatChanges = function () {
    for (var i = 0; i < 9; ++i) {
        var rect = this.itemRect(i + 1);
        this.drawRightArrow(rect);
        this.drawParamName(i, rect);
        this.drawCurrentParam(i, rect);
        this.drawNewParam(i, rect);
        this.drawParamDifference(i, rect);
    }
};

Window_LevelUp.prototype.drawParamName = function (index, rect) {
    var x = rect.x + this.textPadding();
    var y = rect.y;
    if (index === 0) {
        var text = TextManager.level;
    } else if (index === 1) {
        var text = TextManager.hp;
    } else if (index === 2) {
        var text = TextManager.mp;
    } else if (index === 3) {
        var text = TextManager.tp;
    } else {
        var text = TextManager.param(index - 2);
    }
    this.drawText(text, x, y, this._paramNameWidth);
};

Window_LevelUp.prototype.drawRightArrow = function (rect) {
    var x = rect.width + this.textPadding() + rect.x;
    var y = rect.y;
    x -= this._paramValueWidth + this._arrowWidth + this._bonusValueWidth;
    var dw = this.textWidth('\u2192' + ' ');
    this.changeTextColor(this.systemColor());
    this.setSmallerFont();
    this.drawText('\u2192', x, y, dw, 'center');
};

Window_LevelUp.prototype.drawCurrentParam = function (index, rect) {
    var x = rect.width - this.textPadding() + rect.x;
    var y = rect.y;
    x -= this._paramValueWidth * 2 + this._arrowWidth + this._bonusValueWidth;
    this.resetTextColor();
    if (index === 0) {
        var text = Yanfly.Util.toGroup(this._actor._preVictoryLv);
    } else {
        var text = Yanfly.Util.toGroup(this._actor._preVictoryParams[index - 1]);
    }
    this.setSmallerFont();
    this.drawText(text, x, y, this._paramValueWidth, 'right');
    this.resetFontSettings();
};

Window_LevelUp.prototype.drawNewParam = function (index, rect) {
    var x = rect.width - this.textPadding() + rect.x;
    x -= this._paramValueWidth + this._bonusValueWidth;
    var y = rect.y;
    if (index === 0) {
        var newValue = this._actor.level;
        var diffvalue = newValue - this._actor._preVictoryLv;
    } else {
        var newValue = this._actor._postVictoryParams[index - 1];
        var diffvalue = newValue - this._actor._preVictoryParams[index - 1];
    }
    var text = Yanfly.Util.toGroup(newValue);
    //this.changeTextColor(this.paramchangeTextColor(diffvalue));
    this.setSmallerFont();
    this.drawText(text, x, y, this._paramValueWidth, 'right');
    this.resetFontSettings();
};

Window_LevelUp.prototype.drawParamDifference = function (index, rect) {
    if (this._bonusValueWidth <= 0) return;
    var x = rect.width - this.textPadding() + rect.x;
    x -= this._bonusValueWidth;
    var y = rect.y;
    if (index === 0) {
        var newValue = this._actor.level;
        var diffvalue = newValue - this._actor._preVictoryLv;
    } else {
        var newValue = this._actor._postVictoryParams[index - 1];
        var diffvalue = newValue - this._actor._preVictoryParams[index - 1];
    }
    if (diffvalue === 0) return;
    //var actorparam = Yanfly.Util.toGroup(newValue);
    this.changeTextColor(this.paramchangeTextColor(diffvalue));
    var text = Yanfly.Util.toGroup(diffvalue);
    if (diffvalue > 0) {
        text = ' (+' + text + ')';
    } else {
        text = ' (' + text + ')';
    }
    this.setSmallerFont();
    this.drawText(text, x, y, this._bonusValueWidth, 'left');
    this.resetFontSettings();
};

Window_LevelUp.prototype.drawLearnedSkills = function (rect) {
    var x = this.textPadding() + rect.x;
    var y = rect.y;
    var textLearnSkillTitle = TextManager.obtainSkill.format('');
    this.changeTextColor(this.systemColor());
    this.setSmallerFont();
    this.drawText(textLearnSkillTitle, x, y, this.contents.width);
    this.resetFontSettings();
    var iconBoxWidth = Window_Base._iconWidth + 4;
    for (var i = 0; i < Math.min(this._actor._victorySkills.length, this.maxVisibleSkills()); i++) {
        var learnedSkill = this._actor._victorySkills[i];
        this.drawIcon($dataSkills[learnedSkill].iconIndex, x + iconBoxWidth + 2, y + (i + 1) * this.lineHeight());
        this.setSmallerFont();
        this.drawText($dataSkills[learnedSkill].name, x + iconBoxWidth * 2, y + (i + 1) * this.lineHeight());
        this.resetFontSettings();
    };
    if (this._actor._victorySkills.length > this.maxVisibleSkills()) {
        this.setSmallerFont();
        this.drawText('……', x + iconBoxWidth * 2 + this.textWidth($dataSkills[learnedSkill].name), y + i * this.lineHeight());
        this.resetFontSettings();
    }
};

Window_LevelUp.prototype.drawHorzLine = function (y) {
    var lineY = y - 1;
    this.contents.paintOpacity = 48;
    this.contents.fillRect(0, lineY, this.contentsWidth(), 2, this.lineColor());
    this.contents.paintOpacity = 255;
};

Window_LevelUp.prototype.lineColor = function () {
    return this.normalColor();
};

//=============================================================================
// Game_Actor
//=============================================================================
SWDA_LevelUp.Game_Actor_shouldDisplayLevelUp =
    Game_Actor.prototype.shouldDisplayLevelUp;
Game_Actor.prototype.shouldDisplayLevelUp = function () {
    if ($gameParty.inBattle()) return false;
    return SWDA_LevelUp.Game_Actor_shouldDisplayLevelUp.call(this);
};

Game_Actor.prototype.clearVictoryData = function () {
    this._victorySkills = undefined;
    this._preVictoryParams = undefined;
    this._postVictoryParams = undefined;
};

Game_Actor.prototype.isLearnedSkillRaw = function (skillId) {
    return this._skills.contains(skillId);
};


SWDA_LevelUp.Game_Actor_learnSkill = Game_Actor.prototype.learnSkill;
Game_Actor.prototype.learnSkill = function (skillId) {
    if (!this.isLearnedSkillRaw(skillId) && this._victoryPhase) {
        this._victorySkills.push(skillId);
    }
    SWDA_LevelUp.Game_Actor_learnSkill.call(this, skillId);
};

//=============================================================================
// Scene_Battle
//=============================================================================
// 胜利窗口结束后，更新升级窗口
Scene_Battle.prototype.startProcessingLevelUp = function () {
    this._startLevelUp = true;
};

Scene_Battle.prototype.finishVictory = function () {
    SoundManager.playOk();
    this._victoryWindow.close();
    this.startProcessingLevelUp();
};



// 升级步骤控制
SWDA_LevelUp.Scene_Battle_updateVictorySteps =
    Scene_Battle.prototype.updateVictorySteps;
Scene_Battle.prototype.updateVictorySteps = function () {
    if (this._startLevelUp)
        this.updateVictoryLevelUp();
    else
        SWDA_LevelUp.Scene_Battle_updateVictorySteps.call(this);
};

// 若不存在升级窗口，则创建。若按下继续键，则继续下一个升级窗口。
Scene_Battle.prototype.updateVictoryLevelUp = function () {
    if (!this._levelUpWindow) {
        this.createVictoryLevelUp();
    } else if (this.victoryTriggerContinue()) {
        this.continueVictoryLevelUp();
    }
};

// 若满足升级条件，则创建升级窗口
Scene_Battle.prototype.createVictoryLevelUp = function () {
    if (this.meetVictoryLevelUpConditions()) {
        BattleManager.playLevelUpMe();
        this.setupNextAftermathLevelUpActor();
    }
    else {
        this.finishVictoryLevelUp();
    }
};
// 判断是否满足升级条件：待升级角色数>0
Scene_Battle.prototype.meetVictoryLevelUpConditions = function () {
    return BattleManager.aftermathLeveledActors().length > 0;
};

// 继续下一个升级角色：若满足条件则继续，若不满足，则直接结束
Scene_Battle.prototype.continueVictoryLevelUp = function () {
    if (this.meetVictoryLevelUpConditions()) {
        SoundManager.playOk();
        this.setupNextAftermathLevelUpActor();
    } else {
        this.finishVictoryLevelUp();
    }
};

//结束升级窗口
Scene_Battle.prototype.finishVictoryLevelUp = function () {
    if (this._levelUpWindow){
        if(this._levelUpWindow.isOpen()){
            SoundManager.playOk();
            this._levelUpWindow.close();
        }
    }
    this.processVictoryFinish();
    //AudioManager.stopMe();
};

Scene_Battle.prototype.setupNextAftermathLevelUpActor = function () {
    this._levelUpActor = BattleManager.aftermathLeveledActors().shift();

    if (!this._levelUpWindow) {
        this._levelUpWindow = new Window_LevelUp(this._levelUpActor);
        this.addWindow(this._levelUpWindow);
        this._levelUpWindow.open();
    } else {
        this._levelUpWindow.setActor(this._levelUpActor);
    }
};

//=============================================================================
// Utilities
//=============================================================================

Yanfly.Util = Yanfly.Util || {};

if (!Yanfly.Util.toGroup) {
    Yanfly.Util.toGroup = function (inVal) {
        return inVal;
    }
};
